home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
vbcc.lha
/
vbcc
/
supp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-30
|
13KB
|
417 lines
#include "supp.h"
static char FILE_[]=__FILE__;
char *typname[]={"strange","char","short","int","long","float","double","void",
"pointer","array","struct","union","enum","function"};
char *storage_class_name[]={"strange","auto","register","static","extern","typedef"};
char *ename[]={"strange","sequence","move","set+","set-","set*","set/","set%",
"set&","set^","set|","set<<","set>>","?:","lor","land","or",
"eor","and","equal","unequal","lt","le","gt","ge","lsl",
"lsr","add","sub","mul","div","mod","negate",
"not","preinc","postinc","predec","postdec","neg",
"dref-pointer","address-of","cast","call","index",
"dref-struct-pointer","dref-struct","identifier","constant",
"string","member",
"convert-char","convert-short","convert-int","convert-long",
"convert-float","convert-double","convert-void","convert-pointer",
"convert-uchar","convert-ushort","convert-uint","convert-ulong",
"address-of-array","first-element-of-array","pmult",
"allocreg","freereg","pconstant","test","label","beq","bne",
"blt","bge","ble","bgt","bra","compare","push","pop",
"address-of-struct","add-int-to-pointer","sub-int-from-pointer",
"sub-pointer-from-pointer","push-reg","pop-reg","pop-args",
"save-regs","restore-regs","identifier-label","dc","align",
"colon","get-return","set-return","move-from-reg","move-to-reg",
"nop"};
char *empty="";
zchar vchar; zuchar vuchar;
zshort vshort; zushort vushort;
zint vint; zuint vuint;
zlong vlong; zulong vulong;
zfloat vfloat; zdouble vdouble;
zpointer vpointer;
#ifndef DEBUG
int DEBUG;
#endif
int label;
int regs[MAXR+1],regused[MAXR+1];
struct Var *regsv[MAXR+1];
int goto_used;
int ic_count;
zlong max_offset;
int function_calls;
int multiple_ccs;
int lastlabel,return_label;
int only_inline;
struct IC *err_ic;
long maxoptpasses=10;
long optflags;
long inline_size=100;
long unroll_size=200;
long fp_assoc,noaliasopt;
int fline;
char errfname[FILENAME_MAX+1];
struct IC *first_ic,*last_ic;
int float_used;
/* Das haette ich gern woanders */
struct Var *vl1,*vl2,*vl3;
struct Typ *clone_typ(struct Typ *old)
/* Erzeugt Kopie eines Typs und liefert Zeiger auf Kopie. */
{
struct Typ *new;
if(!old) return(0);
new=mymalloc(TYPS);
*new=*old;
if(new->next) new->next=clone_typ(new->next);
return(new);
}
void free_IC(struct IC *p)
/* Gibt IC-Liste inkl. Typen frei. */
{
struct IC *merk;
if(DEBUG&1) printf("free_IC()\n");
while(p){
if(p->q1.am) free(p->q1.am);
if(p->q2.am) free(p->q2.am);
if(p->z.am) free(p->z.am);
merk=p->next;
free(p);
p=merk;
}
}
void remove_IC(struct IC *p)
/* Entfernt IC p aus Liste. */
{
if(p->prev) p->prev->next=p->next; else first_ic=p->next;
if(p->next) p->next->prev=p->prev; else last_ic=p->prev;
if(p->q1.am) free(p->q1.am);
if(p->q2.am) free(p->q2.am);
if(p->z.am) free(p->z.am);
free(p);
}
void freetyp(struct Typ *p)
/* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so. */
{
int f;struct Typ *merk;
if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
while(p){
merk=p->next;
f=p->flags&NQ;
if(merk&&f!=ARRAY&&f!=POINTER&&f!=FUNKT){ierror(0);return;}
free(p);
p=merk;
}
}
zlong falign(struct Typ *t)
/* Liefert Alignment eines Typs. Funktioniert im Gegensatz zum */
/* align[]-Array auch mit zusammengesetzten Typen. */
{
int i,f; zlong al,alt;
f=t->flags&NQ;
al=align[f];
if(f<=POINTER) return al;
if(f==ARRAY){
do{
t=t->next;
f=t->flags&NQ;
}while(f==ARRAY);
alt=falign(t);
if(zlleq(al,alt)) return alt; else return al;
}
if(f==UNION||f==STRUCT){
for(i=0;i<t->exact->count;i++){
alt=falign((*t->exact->sl)[i].styp);
if(!zlleq(alt,al)) al=alt;
}
return al;
}
return al;
}
zlong szof(struct Typ *t)
/* Liefert die benoetigte Groesse eines Typs in Bytes. */
{
int i=t->flags&NQ,j;zlong size,m;
if(i<=POINTER) return sizetab[i];
if(i==ARRAY){
size=zlmult((t->size),szof(t->next));
m=align[ARRAY];
return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
}
if(i==UNION){
for(j=0,size=l2zl(0L);j<t->exact->count;j++){
m=szof((*t->exact->sl)[j].styp);
if(zleqto(m,l2zl(0L))) return(l2zl(0L));
if(!zlleq(m,size)) size=m;
}
m=falign(t);
return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
}
if(i==STRUCT){
for(j=0,size=0;j<t->exact->count;j++){
struct Typ *h=(*t->exact->sl)[j].styp;
m=falign(h);
size=zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m);
m=szof(h);
if(zleqto(m,l2zl(0L))) return(l2zl(0L));
size=zladd(size,m);
}
m=falign(t);
return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
}
return sizetab[i];
}
void printval(FILE *f,union atyps *p,int t,int verbose)
/* Gibt atyps aus. */
{
if(t==CHAR){if(verbose)fprintf(f,"C");vlong=zc2zl(p->vchar);printzl(f,vlong);}
if(t==(UNSIGNED|CHAR)){if(verbose)fprintf(f,"UC");vulong=zuc2zul(p->vuchar);printzul(f,vulong);}
if(t==SHORT){if(verbose)fprintf(f,"S");vlong=zs2zl(p->vshort);printzl(f,vlong);}
if(t==(UNSIGNED|SHORT)){if(verbose) fprintf(f,"US");vulong=zus2zul(p->vushort);printzul(f,vulong);}
if(t==FLOAT){if(verbose)fprintf(f,"F");vdouble=zf2zd(p->vfloat);printzd(f,vdouble);}
if(t==DOUBLE){if(verbose)fprintf(f,"D");printzd(f,p->vdouble);}
if(t==INT){if(verbose)fprintf(f,"I");vlong=zi2zl(p->vint);printzl(f,vlong);}
if(t==LONG){if(verbose)fprintf(f,"L");printzl(f,p->vlong);}
if(t==(UNSIGNED|INT)){if(verbose)fprintf(f,"UI");vulong=zui2zul(p->vuint);printzul(f,vulong);}
if(t==(UNSIGNED|LONG)){if(verbose)fprintf(f,"UL");printzul(f,p->vulong);}
/* das hier ist nicht wirklich portabel */
if(t==POINTER){if(verbose)fprintf(f,"P");vulong=zp2zul(p->vpointer);printzul(f,vulong);}
}
void pric2(FILE *f,struct IC *p)
/* Gibt ein IC aus. */
{
if(p->next&&p->next->prev!=p) ierror(0);
if(p->code>=LABEL&&p->code<=BRA){
if(p->code==LABEL)
fprintf(f,"L%d",p->typf);
else{
fprintf(f,"\t%s L%d",ename[p->code],p->typf);
if(p->q1.flags){ fprintf(f,",");probj(f,&p->q1,0);}
}
}else{
fprintf(f,"\t%s ",ename[p->code]);
if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
if(p->typf) fprintf(f,"%s ",typname[p->typf&NQ]);
probj(f,&p->q1,p->typf);
if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,p->typf);}
if(p->z.flags){fprintf(f,"->");probj(f,&p->z,p->typf);}
if(p->code==ASSIGN||p->code==PUSH||p->code==POP) fprintf(f," size=%ld",zl2l(p->q2.val.vlong));
if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg) fprintf(f," except %s",regnames[p->q1.reg]);
}
fprintf(f,"\n");
}
void pric(FILE *f,struct IC *p)
/* Gibt IC-Liste auf dem Bildschirm aus. */
{
while(p){
pric2(f,p);
/* if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/
p=p->next;
}
}
void printzl(FILE *f,zlong x)
/* Konvertiert zlong nach ASCII. */
/* Basiert noch einigermassen auf */
/* Zweierkomplementdarstellung (d.h. -MIN>MAX). */
/* Ausserdem muss max(abs(long))<=max(unsigned long). */
{
zlong zl;zulong zul;
zl=l2zl(0L);
if(zlleq(x,zl)&&!zleqto(x,l2zl(0L))){
fprintf(f,"-");zl=zul2zl(t_max[LONG]);
if(zlleq(x,zlsub(l2zl(0L),zl))&&!zleqto(x,zlsub(l2zl(0L),zl))){
/* aufpassen, da -x evtl. >LONG_MAX */
zul=t_max[LONG];
x=zladd(x,zl);
} else zul=ul2zul(0UL);
x=zlsub(l2zl(0L),x);
vulong=zl2zul(x);
zul=zuladd(zul,vulong);
}else zul=zl2zul(x);
printzul(f,zul);
}
void printzul(FILE *f,zulong x)
/* Konvertiert zulong nach ASCII. */
{
zulong zul;unsigned long l;
zul=ul2zul(10UL);
if(!zuleqto(zuldiv(x,zul),ul2zul(0UL))) printzul(f,zuldiv(x,zul));
zul=zulmod(x,zul);l=zul2ul(zul);
fprintf(f,"%c",(int)(l+'0'));
}
void printz